
package client;

import common.Utils;
import common.packet.ClientInfo;
import java.awt.Canvas;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;

/**
 * The JPanel of the game. It has a player list, chat box and game panel where
 * jMonkeyEngine renders the graphics.
 *
 * @author xissburg
 */
public class GamePanel extends javax.swing.JPanel implements GameController.EventHandler
{
    private GameController gameController;

    public GamePanel(GameController gameController) {
        initComponents();

        this.gameController = gameController;

        Canvas canvas = gameController.getCanvas();
        topPanel.add(canvas, java.awt.BorderLayout.CENTER);
        topPanel.validate();

        //If client is not owner then disable the startButton
        ClientInfo clientInfo = gameController.getClientInfo();
        if(!clientInfo.isOwner())
            startButton.setEnabled(false);

        //Add action to the chat text field so that when the user presses enter
        //the message is sent
        AbstractAction action = new AbstractAction(){
            public void actionPerformed(ActionEvent e) {
                sendButtonActionPerformed(e);
            }
        };

        inputTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "pressed");
        inputTextField.getActionMap().put("pressed", action);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        topPanel = new javax.swing.JPanel();
        playersPanel = new javax.swing.JPanel();
        playersScroll = new javax.swing.JScrollPane();
        playersList = new javax.swing.JList();
        bottomPanel = new javax.swing.JPanel();
        rightButtonsPanel = new javax.swing.JPanel();
        startButton = new javax.swing.JButton();
        quitButton = new javax.swing.JButton();
        chatPanel = new javax.swing.JPanel();
        textInputPanel = new javax.swing.JPanel();
        sendButton = new javax.swing.JButton();
        inputTextField = new javax.swing.JTextField();
        chatScroll = new javax.swing.JScrollPane();
        chatTextArea = new javax.swing.JTextArea();

        setLayout(new java.awt.BorderLayout());

        topPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2));
        topPanel.setPreferredSize(new java.awt.Dimension(848, 406));
        topPanel.setLayout(new java.awt.BorderLayout());

        playersPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Players"));
        playersPanel.setMinimumSize(new java.awt.Dimension(180, 300));
        playersPanel.setPreferredSize(new java.awt.Dimension(180, 300));
        playersPanel.setLayout(new java.awt.BorderLayout());

        playersList.setModel(new javax.swing.DefaultListModel());
        playersScroll.setViewportView(playersList);

        playersPanel.add(playersScroll, java.awt.BorderLayout.CENTER);

        topPanel.add(playersPanel, java.awt.BorderLayout.LINE_START);

        add(topPanel, java.awt.BorderLayout.CENTER);

        bottomPanel.setLayout(new java.awt.BorderLayout());

        rightButtonsPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
        rightButtonsPanel.setPreferredSize(new java.awt.Dimension(90, 226));
        rightButtonsPanel.setLayout(new javax.swing.BoxLayout(rightButtonsPanel, javax.swing.BoxLayout.Y_AXIS));

        startButton.setText("Start");
        startButton.setAlignmentX(0.5F);
        startButton.setMaximumSize(new java.awt.Dimension(75, 25));
        startButton.setMinimumSize(new java.awt.Dimension(43, 25));
        startButton.setPreferredSize(new java.awt.Dimension(75, 25));
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });
        rightButtonsPanel.add(startButton);

        quitButton.setText("Quit");
        quitButton.setAlignmentX(0.5F);
        quitButton.setMaximumSize(new java.awt.Dimension(75, 25));
        quitButton.setMinimumSize(new java.awt.Dimension(43, 25));
        quitButton.setPreferredSize(new java.awt.Dimension(75, 25));
        quitButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                quitButtonActionPerformed(evt);
            }
        });
        rightButtonsPanel.add(javax.swing.Box.createVerticalGlue());
        rightButtonsPanel.add(quitButton);

        bottomPanel.add(rightButtonsPanel, java.awt.BorderLayout.LINE_END);

        chatPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Chat"));
        chatPanel.setMinimumSize(new java.awt.Dimension(180, 81));
        chatPanel.setLayout(new java.awt.BorderLayout());

        textInputPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2));
        textInputPanel.setPreferredSize(new java.awt.Dimension(630, 30));
        textInputPanel.setLayout(new java.awt.BorderLayout());

        sendButton.setText("Send");
        sendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sendButtonActionPerformed(evt);
            }
        });
        textInputPanel.add(sendButton, java.awt.BorderLayout.LINE_END);
        textInputPanel.add(inputTextField, java.awt.BorderLayout.CENTER);

        chatPanel.add(textInputPanel, java.awt.BorderLayout.PAGE_END);

        chatScroll.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2, 2, 2), javax.swing.BorderFactory.createLineBorder(new java.awt.Color(127, 127, 128))));
        chatScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        chatTextArea.setColumns(20);
        chatTextArea.setEditable(false);
        chatTextArea.setFont(new java.awt.Font("Monospaced", 0, 12));
        chatTextArea.setLineWrap(true);
        chatTextArea.setRows(5);
        chatScroll.setViewportView(chatTextArea);

        chatPanel.add(chatScroll, java.awt.BorderLayout.CENTER);

        bottomPanel.add(chatPanel, java.awt.BorderLayout.CENTER);

        add(bottomPanel, java.awt.BorderLayout.PAGE_END);
    }// </editor-fold>//GEN-END:initComponents

    private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed
        final String message = inputTextField.getText();
        inputTextField.setText(null);

        if(message != null && message.length() > 0)
        {
            new SwingWorker<Void, Void>()
            {
                @Override
                protected Void doInBackground()
                {
                    gameController.sendChatMessage(message);
                    return null;
                }
            }.execute();
        }
    }//GEN-LAST:event_sendButtonActionPerformed

    private void quitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quitButtonActionPerformed
        //Send logout packet to server
        new SwingWorker<Void, Void>()
        {
            @Override
            protected Void doInBackground()
            {
                gameController.logout();
                return null;
            }
        }.execute();
    }//GEN-LAST:event_quitButtonActionPerformed

    private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed

        ClientInfo clientInfo = gameController.getClientInfo();
        
        if(clientInfo.isOwner())
        {
            //Disable StartGame button
            startButton.setEnabled(false);
            //Send packet to server
            new SwingWorker<Void, Void>()
            {
                @Override
                protected Void doInBackground()
                {
                    gameController.startGame();
                    return null;
                }
            }.execute();
        }
    }//GEN-LAST:event_startButtonActionPerformed

    public void appendChatMessage(String msg)
    {
        chatTextArea.append(msg);
        javax.swing.JScrollBar vScroll = chatScroll.getVerticalScrollBar();
        vScroll.setValue(vScroll.getMaximum());
    }

    public void addClient(final ClientInfo client)
    {
        DefaultListModel dtm = (DefaultListModel)playersList.getModel();
        dtm.addElement(client.getName());
    }

    public void removeClient(String name)
    {
        DefaultListModel dtm = (DefaultListModel)playersList.getModel();
        dtm.removeElement(name);
    }

    public void error(final String message)
    {
        Utils.runInEDT(new Runnable() {
            public void run() {
                JOptionPane.showMessageDialog(GamePanel.this, message,
                    "Error", JOptionPane.ERROR_MESSAGE);
            }
        });
    }

    public void connected() {}

    public void gameCreated() {}

    public void clientJoined(final ClientInfo clientInfo) {
        Utils.runInEDT(new Runnable() {
            public void run() {
                addClient(clientInfo);
                appendChatMessage("<" + clientInfo.getName() + " joined the game>\n");
            }
        });
    }

    public void clientQuit(final ClientInfo clientInfo) {
        Utils.runInEDT(new Runnable() {
            public void run() {
                String name = clientInfo.getName();
                removeClient(name);
                appendChatMessage("<" + name + " quit>\n");
            }
        });
    }

    public void chatMessage(final String message) {
        Utils.runInEDT(new Runnable() {
            public void run() {
                appendChatMessage(message + "\n");
            }
        });
    }

    public void disconnected(final String message) {
        Utils.runInEDT(new Runnable() {
            public void run() {
                if(message != null)
                {
                    JOptionPane.showMessageDialog(GamePanel.this,
                            "Disconnected from server.\n" +message, "Error",
                            JOptionPane.ERROR_MESSAGE);
                }
                //Go back to login screen
                Container parent = GamePanel.this.getParent();
                parent.removeAll();
                LoginPanel loginPanel = new LoginPanel(gameController);
                gameController.setEventHandler(loginPanel);
                parent.add(loginPanel);
                parent.validate();
            }
        });
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel bottomPanel;
    private javax.swing.JPanel chatPanel;
    private javax.swing.JScrollPane chatScroll;
    private javax.swing.JTextArea chatTextArea;
    private javax.swing.JTextField inputTextField;
    private javax.swing.JList playersList;
    private javax.swing.JPanel playersPanel;
    private javax.swing.JScrollPane playersScroll;
    private javax.swing.JButton quitButton;
    private javax.swing.JPanel rightButtonsPanel;
    private javax.swing.JButton sendButton;
    private javax.swing.JButton startButton;
    private javax.swing.JPanel textInputPanel;
    private javax.swing.JPanel topPanel;
    // End of variables declaration//GEN-END:variables

}
